﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;

namespace SBLib.Common.CsvKS
{
    public class CsvReadFuncKS
    {
        public static long CsvLineCount(string prmFilePath)
        {
            try
            {
                if (string.IsNullOrEmpty(prmFilePath) || string.IsNullOrWhiteSpace(prmFilePath))
                {
                    throw new Exception("csv file location missing");
                }

                using (StreamReader readFile = new StreamReader(prmFilePath))
                {
                    string line = readFile.ReadToEnd();

                    Regex RE = new Regex("\n", RegexOptions.Multiline);
                    MatchCollection theMatches = RE.Matches(line);
                    return theMatches.Count;

                }

            }
            catch (Exception)
            {
                return 0;
            }
        }

        public static List<string[]> CsvToList(string prmFilePath, bool prmIncluedeHeader)
        {
            if (string.IsNullOrEmpty(prmFilePath) || string.IsNullOrWhiteSpace(prmFilePath))
            {
                throw new Exception("csv file location missing");
            }

            try
            {
                using (StreamReader readFile = new StreamReader(prmFilePath))
                {
                    string line;
                    string[] row;

                    List<string[]> dataStore = new List<string[]>();
                    //int ctr = 1;
                    while ((line = readFile.ReadLine()) != null)
                    {
                        //Console.WriteLine(ctr.ToString());
                        //ctr = ctr + 1;
                        Regex regexObj = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
                        row = regexObj.Split(line);
                        dataStore.Add(row);
                    }

                    return dataStore;
                }

            }
            catch (Exception)
            {
                return null;
            }
        }


        public static DataTable CsvToDataTable(string prmFilePath, bool prmIncluedeHeader)
        {
            try
            {
                return csvToTable(prmFilePath, prmIncluedeHeader, "", null,null, "", null,null);
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }

        }

        public static DataTable CsvToDataTable(string prmFilePath, bool prmIncluedeHeader, string prmPrimary, Type prmPrimayType, object prmPrimaryVal,  string prmForeign, Type prmForeignType,object prmForeignVal)
        {
            try
            {
                return csvToTable(prmFilePath, prmIncluedeHeader, prmPrimary, prmPrimayType,prmPrimaryVal, prmForeign, prmForeignType,prmForeignVal );
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        private static DataTable csvToTable(string prmFilePath, bool prmIncluedeHeader, string prmPrimary, Type prmPrimayType, object prmPrimaryVal, string prmForeign, Type prmForeignType, object prmForeignVal)
        {
            if (string.IsNullOrEmpty(prmFilePath) || string.IsNullOrWhiteSpace(prmFilePath))
            {
                throw new Exception("csv file location missing");
            }

            try
            {
                using (StreamReader readFile = new StreamReader(prmFilePath))
                {
                    string line;
                    string[] fieldCollection;

                    DataTable csvDataTable = new DataTable();

                    //int ctr = 1;
                    while ((line = readFile.ReadLine()) != null)
                    {

                        //Console.WriteLine(ctr.ToString());
                        //ctr = ctr + 1;
                        Regex regexObj = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
                        fieldCollection = regexObj.Split(line);

                        if (prmIncluedeHeader == true)
                        {
                            if (prmPrimary.Trim() != "" && prmPrimayType != null)
                            {
                                csvDataTable.Columns.Add(prmPrimary.Trim(), typeof(long));
                            }

                            if (prmForeign.Trim() != "" && prmForeignType != null)
                            {
                                csvDataTable.Columns.Add(prmForeign.Trim(), typeof(long));
                            }


                            foreach (var sngField in fieldCollection)
                            {
                                csvDataTable.Columns.Add(sngField, typeof(string));
                            }
                            prmIncluedeHeader = false;
                        }
                        else
                        {
                            int ctr = 0;
                            DataRow dtrow = csvDataTable.NewRow();

                            bool keyFlag = false;
                            foreach (var rowField in fieldCollection)
                            {
                                if (keyFlag == false)
                                {
                                    if (prmPrimary.Trim() != "" && prmPrimayType != null)
                                    {
                                        dtrow[ctr] = prmPrimaryVal;
                                        ctr = ctr + 1;
                                    }

                                    if (prmForeign.Trim() != "" && prmForeignType != null)
                                    {
                                        dtrow[ctr] = prmForeignVal;
                                        ctr = ctr + 1;
                                    }

                                    keyFlag = true;
                                }

                                dtrow[ctr] = rowField;
                                ctr = ctr + 1;

                            }

                            csvDataTable.Rows.Add(dtrow);
                        }
                    }

                    return csvDataTable;

                }

            }
            catch (Exception)
            {
                return null;
            }
        }


        public static string[] CsvHeaderToDataTable(string prmFilePath)
        {
            if (string.IsNullOrEmpty(prmFilePath) || string.IsNullOrWhiteSpace(prmFilePath))
            {
                throw new Exception("csv file location missing");
            }

            try
            {
                using (StreamReader readFile = new StreamReader(prmFilePath))
                {
                    string line;
                    string[] fieldCollection;

                    DataTable csvDataTable = new DataTable();

                    while ((line = readFile.ReadLine()) != null)
                    {
                        Regex regexObj = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
                        fieldCollection = regexObj.Split(line);


                        //foreach (var sngField in fieldCollection)
                        //{
                        //    csvDataTable.Columns.Add(sngField, typeof(string));
                        //}

                        return fieldCollection;

                    }

                    return null;

                }

            }
            catch (Exception)
            {
                return null;
            }
        }


        public static string GetCsvString(DataTable dt, string delimiter)
        {
            try
            {
                if (dt == null)
                {
                    return "";
                }
                // Header
                StringBuilder _swFile = new StringBuilder();

                string[] colLbls = new string[dt.Columns.Count];

                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    colLbls[i] = dt.Columns[i].ColumnName;
                    colLbls[i] = GetWriteableValueForCsv(colLbls[i], delimiter);
                }

                // Write labels
                _swFile.Append(string.Format("{0}{1}", string.Join(delimiter, colLbls), Environment.NewLine));

                // Rows of Data
                foreach (DataRow rowData in dt.Rows)
                {
                    string[] colData = new string[dt.Columns.Count];

                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        object obj = rowData[i];
                        colData[i] = GetWriteableValueForCsv(obj, delimiter);
                    }

                    // Write data in row
                    _swFile.Append(string.Format("{0}{1}", string.Join(delimiter, colData), Environment.NewLine));
                }

                return _swFile.ToString();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);

            }
        }

        private static string GetWriteableValueForCsv(object obj, string delimiter)
        {
            try
            {
                // Nullable types to blank
                if (obj == null || obj == Convert.DBNull)
                    return "";

                // if string has no ','
                if (obj.ToString().IndexOf(delimiter) == -1)
                    return obj.ToString();

                // remove backslahes
                return "\"" + obj.ToString() + "\"";
            }
            catch (Exception)
            {

                return "";
            }

        }
    }
}
